package com.xinke.component.web.web.config;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;

import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;

/**
 * Description:
 *
 * @Author yzx
 * @Create 2025/3/12 23:52
 * @Version 1.0
 *
 * @ConfigurationProperties(prefix = "xinke.web")
 * 作用: 将配置文件（如 application.yml 或 application.properties）中的属性批量绑定到 Java 对象。
 * 用途:
 * 将前缀为 xinke.web 的配置项映射到类的字段上。
 * 例如，配置文件中定义 xinke.web.title=MyApp，则该值会被注入到类的 title 字段。
 * @Validated
 * 作用: 启用 JSR-303/JSR-349 数据校验，确保配置属性的合法性。
 * 用途:
 * 结合校验注解（如 @NotNull、@Size、@Pattern）对配置值进行验证。
 * 如果配置不合法，应用启动时会抛出异常，防止无效配置。
 * @Data
 * 作用: Lombok 注解，自动生成类的 getter、setter、toString()、equals()、hashCode() 等方法。
 * 用途:
 * 减少样板代码，无需手动编写 getter/setter。
 * 依赖 Lombok 插件和库（需在项目中添加 Lombok 依赖）。
 *
 */
@ConfigurationProperties(prefix = "xinke.web")
@Validated
@Data
public class WebProperties {

    @NotNull(message = "APP API 不能为空")
    private Api appApi = new Api("/app-api", "**.controller.app.**");
    @NotNull(message = "Admin API 不能为空")
    private Api adminApi = new Api("/admin-api", "**.controller.admin.**");

    @NotNull(message = "Admin UI 不能为空")
    private Ui adminUi;

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    @Valid
    public static class Api {

        /**
         * API 前缀，实现所有 Controller 提供的 RESTFul API 的统一前缀
         * 意义：通过该前缀，避免 Swagger、Actuator 意外通过 Nginx 暴露出来给外部，带来安全性问题
         *      这样，Nginx 只需要配置转发到 /api/* 的所有接口即可。
         *
         * @see XinkeWebAutoConfiguration#configurePathMatch(PathMatchConfigurer)
         */
        @NotEmpty(message = "API 前缀不能为空")
        private String prefix;

        /**
         * Controller 所在包的 Ant 路径规则
         *
         * 主要目的是，给该 Controller 设置指定的 {@link #prefix}
         */
        @NotEmpty(message = "Controller 所在包不能为空")
        private String controller;
    }

    @Data
    @Valid
    public static class Ui {
        /**
         * 访问地址
         */
        private String url;

    }
}
